/**
 * @file ui_change.c
 * @author your name (you@domain.com)
 * @brief ui change
 * @version 0.1
 * @date 2023-06-03
 *
 * @copyright Copyright (c) 2023
 *
 */
#include "ui_change.h"
#include "ui_top.h"
#include "ui_config.h"
#include "ui_toast.h"
#include "stack.h"

#define UI_STACK_DEEP (10)

typedef struct ui_change_status
{
   ui_basic_com_t *cur_ui_basic;
   ui_basic_com_t *last_ui_basic;
   int cur_ui_id; 
   stack_t *ui_stack;
} ui_change_status_t;

static ui_change_status_t s_ui_change_status = {0};

static void main_sub_page_switch_handle(int ui_id)
{
   //  if(ui_is_main_page(s_ui_change_status.cur_ui_id))
   //  {
   //     if(ui_is_sub_page(ui_id))
   //     {
   //        COMLOG_INFO_LOG("main to sub page, push main to stack\n");
   //        stack_push(s_ui_change_status.ui_stack, (void *)ui_page_get(s_ui_change_status.cur_ui_id));
   //     }
   //  }
   //  else 
    COMLOG_INFO_LOG("page %x to %x\n", s_ui_change_status.cur_ui_id, ui_id);
    if(ui_is_sub_page(s_ui_change_status.cur_ui_id))
    {
       if(ui_is_main_page(ui_id))
       {
          COMLOG_INFO_LOG("sub to main page, clear stack\n");
          stack_clear_all(s_ui_change_status.ui_stack);
       }
    }
}

static void _ui_change(int ui_id)
{
   easy_ui_page_info_t *ui_page = ui_page_get(ui_id);

   if (ui_page != NULL && ui_page->page != NULL)
   {
      if (s_ui_change_status.cur_ui_basic != NULL)
      {
         if (s_ui_change_status.cur_ui_basic->exit)
         {
            s_ui_change_status.cur_ui_basic->exit(0, 0, NULL);
         }
      }
      s_ui_change_status.last_ui_basic = s_ui_change_status.cur_ui_basic;
      s_ui_change_status.cur_ui_basic = ui_page->page();
      if (s_ui_change_status.cur_ui_basic->enter != NULL)
      {
         s_ui_change_status.cur_ui_basic->enter(0, 0, NULL);
      }
   }
}

static void change_to_last_ui(void)
{
   if(ui_is_main_page(s_ui_change_status.cur_ui_id) == 0)
   {
      return;
   }
   int ui_count = ui_main_array_len();
   int last_one_main_ui_id = g_main_ui_array[ui_count-1].id;
   int first_main_ui_id = g_main_ui_array[0].id;
   if (s_ui_change_status.cur_ui_id == last_one_main_ui_id)
   {
      ui_change_ui(first_main_ui_id, false);
   }
   else
   {
      ui_change_ui(s_ui_change_status.cur_ui_id + 1, false);
   }
}

static void change_to_next_ui(void)
{
   if(ui_is_main_page(s_ui_change_status.cur_ui_id) == 0)
   {
      return;
   }
   int ui_count = ui_main_array_len();
   int last_one_main_ui_id = g_main_ui_array[ui_count-1].id;
   int first_main_ui_id = g_main_ui_array[0].id;
   if (s_ui_change_status.cur_ui_id == first_main_ui_id)
   {
      ui_change_ui(last_one_main_ui_id, false);
   }
   else
   {
      ui_change_ui(s_ui_change_status.cur_ui_id - 1, false);
   }
}

static void back_to_last_ui(void)
{
   easy_ui_page_info_t* ui_page = (easy_ui_page_info_t*)stack_pop(s_ui_change_status.ui_stack);
   if(ui_page != NULL)
   {
      COMLOG_INFO_LOG("back to page: %d\n", ui_page->id);
      ui_change_ui(ui_page->id, false);
   }
   else
   {
      COMLOG_INFO_LOG("stack pop fail, maybe is empty\n");
   }
}

void ui_change_event(char *event_name, void *data, int srcId)
{
   COMLOG_INFO_LOG("ui change: %s\n", event_name);
   if (strcmp(event_name, TOPIC_INIT_TOP_UI) == 0)
   {
      g_sub_ui_array[0].page()->enter(0, 0, NULL);
   }
   else if (strcmp(event_name, TOPIC_CHANGE_UI) == 0)
   {
      if (data == NULL)
      {
         COMLOG_ERROR_LOG("change ui , data is null");
         return;
      }
      int ui_id = -1;
      memcpy(&ui_id, data, sizeof(int));
      _ui_change(ui_id);
   }
   else if (strcmp(event_name, TOPIC_RUN_UI) == 0)
   {
      if (s_ui_change_status.cur_ui_basic != NULL)
      {
         if (s_ui_change_status.cur_ui_basic->run /*&& s_ui_change_status.cur_ui_basic.is_loop*/)
         {
            s_ui_change_status.cur_ui_basic->run(0, 0, NULL);
         }
      }
   }
   else if (strcmp(event_name, TOPIC_TOAST_INFO) == 0)
   {
      ui_toast_show((char *)data, TOAST_SHOW_INFO);
   }
   else if (strcmp(event_name, TOPIC_TOAST_WARN) == 0)
   {
      ui_toast_show((char *)data, TOAST_SHOW_WARNING);
   }
   else if (strcmp(event_name, TOPIC_TOAST_ERR) == 0)
   {
      ui_toast_show((char *)data, TOAST_SHOW_ERROR);
   }
   else if (strcmp(event_name, TOPIC_TOAST_INFO_DEL) == 0)
   {
      ui_toast_show((char *)data, TOAST_SHOW_INFO_WAIT_DEL);
   }
   else if (strcmp(event_name, TOPIC_TOAST_WARN_DEL) == 0)
   {
      ui_toast_show((char *)data, TOAST_SHOW_WARNING_WAIT_DEL);
   }
   else if (strcmp(event_name, TOPIC_TOAST_ERR_DEL) == 0)
   {
      ui_toast_show((char *)data, TOAST_SHOW_ERROR_WAIT_DEL);
   }  
   else if (strcmp(event_name, TOPIC_BACK_UI) == 0)
   {
      back_to_last_ui();
   }
   else if (strcmp(event_name, TOPIC_NEXT_UI) == 0)
   {
      change_to_next_ui();
   }
   else if (strcmp(event_name, TOPIC_LAST_UI) == 0)
   {
      change_to_last_ui();
   }
}

int ui_change_ui(easy_ui_id_e ui_id, bool is_push_stack)
{
   static int _ui_id = -1;
   if (_ui_id == ui_id)
   {
      return -1;
   }
   _ui_id = ui_id;
   main_sub_page_switch_handle(ui_id);
   if(is_push_stack)
   {
       if(stack_is_full(s_ui_change_status.ui_stack))
       {
          stack_pop(s_ui_change_status.ui_stack);
       }
       stack_push(s_ui_change_status.ui_stack, (void *)ui_page_get(s_ui_change_status.cur_ui_id));
   }
   s_ui_change_status.cur_ui_id = ui_id;
   return easy_ui_pub_event(TOPIC_CHANGE_UI, (void *)&_ui_id, sizeof(int), 0);
}

int ui_change_manage(void)
{
   easy_ui_sub_event(TOPIC_INIT_TOP_UI, ui_change_event, ANY_ID);
   easy_ui_sub_event(TOPIC_CHANGE_UI, ui_change_event, ANY_ID);
   easy_ui_sub_event(TOPIC_RUN_UI, ui_change_event, ANY_ID);
   easy_ui_sub_event(TOPIC_TOAST_INFO, ui_change_event, ANY_ID);
   easy_ui_sub_event(TOPIC_TOAST_WARN, ui_change_event, ANY_ID);
   easy_ui_sub_event(TOPIC_TOAST_ERR, ui_change_event, ANY_ID);
   easy_ui_sub_event(TOPIC_TOAST_INFO_DEL, ui_change_event, ANY_ID);
   easy_ui_sub_event(TOPIC_TOAST_WARN_DEL, ui_change_event, ANY_ID);
   easy_ui_sub_event(TOPIC_TOAST_ERR_DEL, ui_change_event, ANY_ID);
   easy_ui_sub_event(TOPIC_BACK_UI, ui_change_event, ANY_ID);
   easy_ui_sub_event(TOPIC_NEXT_UI, ui_change_event, ANY_ID);
   easy_ui_sub_event(TOPIC_LAST_UI, ui_change_event, ANY_ID);
   easy_ui_sub_event(TOPIC_DROP_DOWN_UI, ui_change_event, ANY_ID);
   easy_ui_sub_event(TOPIC_DROP_UP_UI, ui_change_event, ANY_ID);
   s_ui_change_status.ui_stack = stack_create(UI_STACK_DEEP);
   if(s_ui_change_status.ui_stack == NULL)
   {
      COMLOG_ERROR_LOG("ui stack create fail\n");
      return -1;
   }
   s_ui_change_status.cur_ui_id = EASY_UI_POWER_ON;
   return 0;
}